#ifndef	__KERNEL_H
#define	__KERNEL_H

#include	<types.h>
#include	<grub.h>

void		(*elfentry)(void);

#define		CHECK_FLAG(flags,bit) ((flags) & (1 << (bit)))

#define		ERR_NO_ERROR	0
#define		ERR_MAGIC	1
#define		ERR_NO_VARS	2
#define		ERR_GDT		3
#define		ERR_IDT		4
#define		ERR_PAGING	5


/* Kernel Flags */
#define		KF_VARS		(1 << ERR_NO_VARS)
#define		KF_GDT		(1 << ERR_GDT)
#define		KF_IDT		(1 << ERR_IDT)
#define		KF_PAGING	(1 << ERR_PAGING)

extern	multiboot_info_t *mbi;
extern	char_t	*g_end[], *g_code[], *g_data[], *g_bss[], *load_adr[], *load_adr_v[];
extern	ulong_t		virt2phys;
volatile ushort_t	KCODE32, KDATA32, KTSS_SEL;
uchar_t	inMain;

typedef struct i386_regs
{
    unsigned int gs, fs, es, ds;
    unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;
    unsigned int int_no, err_code;
    unsigned int eip, cs, eflags, useresp, ss;
} regs_t;

/* rw_crx.asm */
uint_t	read_cr0();
uint_t	read_cr3();
void	write_cr0(uint_t);
void	write_cr3(uint_t);

/**/
void	force_end();

void	kbasic_gdt_setup();
uint_t	get_root_pages();
void	kbasic_paging_setup(int_t);
void	kbasic_idt_setup();
void	kbasic_mm_setup();

/* kernel.c */
void	kbasic_set_flag(ulong_t);
void	kbasic_initialize();
void	kbasic_error(int_t);
void	kbasic_skip_main(long_t);

ulong_t	kbasic_get_flags();
ulong_t	kbasic_get_v2p();
ulong_t	kbasic_get_ex_mem();

void*	virtual2physical(void*);
void*	physical2virtual(void*);

void	enable();
void	disable();

void	kbasic_irq_setup(uchar_t , void*);

void	kbasic_install_safe_keyboard();

#define	MAX_ERROR_CODES	5
extern char_t	*err_codes[];

typedef struct idt_entry	idt_entry_t;

enum _dpl
{
	RING0, RING1, RING2, RING3
};

typedef enum _dpl	dpl_t;

#define NM_MEMORY 0xABCD

typedef struct{
	uint_t  magic;
	uint_t  size;
	void   *next;  
} mmblock_t;

void*	kmalloc(ulong_t);
void*	kzmalloc(ulong_t);
void* 	krealloc(void *, ulong_t);
void	kfree(void*);


typedef struct{
	unsigned adr, size, flags;
	unsigned long offset;
} sect_t;

typedef struct{
	char *user_mem;	
	unsigned virt_adr;
	unsigned size;

	unsigned magic, num_sects;
	sect_t *sect;
} aspace_t;

#define	AS_MAGIC	0xDCBA

#define	CONSOLE_COUNT	4
void	console_install();
void	console_switch(uint_t);
uint_t	console_current();
void	kprintf(const char*, ...);
void	putchar(int);
void	cls();

#endif	/* __KERNEL_H */
